﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using Odyssey.Linq;
using Odyssey.Web.Models;
using log4net;
using Microsoft.Practices.Unity;
using SunTzu.Core.Authorization;
using SunTzu.Core.Data;
using SunTzu.Utility;
using SunTzu.Web;
using System.Web.Routing;

namespace Odyssey.Web.Areas.Admin.Controllers
{
    public class BaseController<T> : Controller where T : class, IEntity, new()
    {
        private ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        [Dependency]
        public IAuthorization Authorization
        {
            get;
            set;
        }

        protected OdysseyDataContext db
        {
            get { return DataContextManager.GetContext(); }
        }

        protected int pageSize = ConfigurationManager.AppSettings["PageSize"].ParseToInt(20);
        protected int numPerPage
        {
            get
            {
                // 从 cookie 读入列表行数
                var cookie = System.Web.HttpContext.Current.Request.Cookies["numPerPage"];
                return cookie == null ? pageSize : cookie.Value.ParseToInt(20);
            }
        }

        protected IQueryable<T> GetTable<T>() where T : class, IEntity, new()
        {
            return db.GetTable<T>();
        }

        protected IQueryable<T> table
        {
            get
            {
                return db.GetTable<T>();
            }
        }

        //protected ILogger Logger
        //{
        //    get
        //    {
        //        return LogManager.GetInstance().GetLogger();
        //    }
        //}
        #region Base Action

        public virtual ActionResult List(int? page)
        {
            ViewData.Model = table
                // .Where(c => c.State > -1) // 过滤被逻辑删除的数据
                .OrderByDescending(c => c.Id)
                .ToPagedList(page.GetValueOrDefault(), numPerPage);
            return View();
        }

        public virtual ActionResult Edit(int? id)
        {
            T entity = id > 0
                ? table.FirstOrDefault(c => c.Id == id) // 编辑
                : new T(); // 添加
            ViewData.Model = entity ?? new T();
            AfterModelLoad(entity);
            return View();
        }

        public virtual ActionResult Detail(int? id)
        {
            T entity = id > 0
                ? table.FirstOrDefault(c => c.Id == id)
                : new T();
            ViewData.Model = entity ?? new T();
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public virtual ActionResult Save(int? id)
        {
            return Save(id, "List");
        }

        public virtual ActionResult Save(int? id, string view)
        {
            T entity = id > 0
                ? table.FirstOrDefault(c => c.Id == id) // 编辑
                : new T(); // 添加

            HTMLHelper.BindModel(entity);
            BeforeSaveOrUpdate(entity);

            if (entity.SaveOrUpdate())
            {
                CacheHelper<T>.Clear();
                var routeValues = BuildRouteValues(entity);
                ProcessRouteValues(routeValues, entity);
                return RedirectToAction(view, routeValues);
            }
            else
            {
                return View("Edit", entity);
            }
        }

        protected virtual RouteValueDictionary BuildRouteValues(T entity)
        {
            var routeValues = new RouteValueDictionary();
            routeValues.Add("area", "Admin");
            if (!string.IsNullOrEmpty(Request.QueryString["classid"]))
            {
                routeValues.Add("classid", Request.QueryString["classid"]);
            }
            return routeValues;
        }

        protected virtual void ProcessRouteValues(RouteValueDictionary routeValues, T entity)
        {
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public virtual JsonResult Delete(string ids)
        {
            if (ids.IsNotNullOrEmpty())
            {
                var entityList = new List<IEntity>();
                int did;
                foreach (var id in ids.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    did = id.ParseToInt();
                    T entity = table.FirstOrDefault(c => c.Id.Equals(did));
                    if (entity != null)
                    {
                        entityList.Add(entity);
                    }
                }
                if (entityList.Delete(false))
                {
                    CacheHelper<T>.Clear();
                    return ReturnResultFactory.DeleteSuccess.ToJsonResult();
                }
            }
            return ReturnResultFactory.Failed.ToJsonResult();
        }
        #endregion

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var container = HttpContext.Application["Container"] as UnityContainer;
            container.BuildUp(this);

            ViewBag.IsLogin = Session[WebConstants.CurrentUser] != null;
            if (ViewBag.IsLogin)
            {
                ViewBag.CurrentUser = Session[WebConstants.CurrentUser];
            }
        }

        protected override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            DataContextManager.Clear();
            base.OnResultExecuted(filterContext);
        }
        protected virtual void AfterModelLoad(T entity) { }
        protected virtual void BeforeSaveOrUpdate(T entity) { }

        protected void SetMessage(string message)
        {
            TempData["Message"] = message;
        }
    }
}
